-- 导入redis模块
local redis = require("resty.redis")  
-- 获取本地共享词典（本地缓存）
local local_cache = ngx.shared.item_local_cache
-- 日志
local ngx_log = ngx.log  
local ngx_ERR = ngx.ERR
-- 关闭redis连接的工具方法
local function close_redis(red)  
    if not red then  
        return  
    end  
    --释放连接(连接池实现)  
    local pool_max_idle_time = 10000 --毫秒  
    local pool_size = 100 --连接池大小  
    local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)  
  
    if not ok then  
        ngx_log(ngx_ERR, "set redis keepalive error : ", err)  
    end  
end

function read_redis(ip, port, key)
     -- 建立连接
     local red = redis:new()
     red:set_timeout(1000) 
     local ok, err = red:connect(ip, port)  
     if not ok then  
        ngx_log(ngx_ERR, "connect to redis error : ", err)  
         return close_redis(red)  
     end 
 
     -- 读数据
     local resp, err = red:get(key)
     if not resp then  
         ngx_log(ngx_ERR, "read redis err: ", err)  
         return close_redis(red)  
     end
     --得到的数据为空处理  
     if resp == ngx.null then  
        resp = nil  
     end
     close_redis(red) 
     return resp;
end

function read_http(path,args)
    -- 内部请求捕获
    local resp, err = ngx.location.capture("/backend/page" .. path,{
        method = ngx.HTTP_GET,
        args = args
    });
    if not resp then  
        ngx_log(ngx_ERR, "read http err: ", err)
        return
    end
    -- 返回状态码不是200就报错
    if resp.status ~= 200 then  
        ngx_log(ngx_ERR, "request error, status :", resp.status)  
        return  
    end
    return resp.body;
end

-- 先查询redis，如果失败，再查询tomcat
function read_data(ip, port, key, path, args)
    -- 先查询redis
    local resp = read_redis(ip, port, key)
    -- 判断是否为nil
    if not resp then
        -- redis查询失败了，缓存为命中，需要去tomcat查询
        ngx_log(ngx_ERR, "redis not fount, back to http, key: "..key)
        -- tomcat查询
        resp = read_http(path, args)
        if not resp then
            -- http查询失败了，彻底失败了，返回404状态码
            ngx_log(ngx_ERR, "http not fount, back to http, path: "..path)
            return nil
        end
    end
    return resp;
end
-- 读取本地缓存
local function cache_get(key)  
    if not local_cache then  
        return nil  
    end  
    return local_cache:get(key)  
end
-- 写入本地缓存
local function cache_set(key, value)  
    if not local_cache then  
        return nil  
    end  
    return local_cache:set(key, value, 30 * 60) --30分钟  
end
-- 先查询本地缓存，缓存不存在先查询redis，如果失败，再查询tomcat 如果成功，写入本地缓存
function read_cache(ip, port, key, path, args)
    -- 查询本地缓存
    local resp = cache_get(key)
    if resp then
        return resp
    end
    ngx_log(ngx_ERR, "local cache not fount, back to redis, key: "..key)
    -- 先查询redis
    resp = read_redis(ip, port, key)
    -- 判断是否为nil
    if not resp then
        -- redis查询失败了，缓存为命中，需要去tomcat查询
        ngx_log(ngx_ERR, "redis not fount, back to http, key: "..key)
        -- tomcat查询
        resp = read_http(path, args)
        if not resp then
            -- http查询失败了，彻底失败了，返回404状态码
            ngx_log(ngx_ERR, "http not fount, back to http, path: "..path)
            return nil
        end
    end
    -- 写入本地缓存
    cache_set(key, resp)
    return resp;
end
local module = {
    read_redis = read_redis,
    read_http = read_http,
    read_data = read_data,
    read_cache = read_cache
}
return module